<script setup>
import {computed, defineEmits, inject, provide, reactive, ref, watch} from "vue";
import 'jiuqi-ui'
import DriverItemDetail from "./DriverItemDetail.vue";

//================================================【公用相关】============================================================
//获取  当前 模型ID
const {currAbcModelGuid} = inject('abcmodel')

const context = inject('context')

//获取动因信息(动因编码、动因名称)
const driver = reactive({code:'',name:''})

//获取动因维度信息
const dimInfoArr = reactive([])

//将 已选择的 维度信息 传递给 子组件（DriverItemDetail）,供其控制 其下拉组件 中 选项是否 失效
provide('dimInfoArr',dimInfoArr)
//当前 动因 绑定的 维度信息 和 维度项信息 数组
const dimAndItemInfoArr = reactive([])

//是否 从 动因页面 进入 动因详情页面
const isEnterFromDriverTable = ref(true)

//================================================【组件通信】============================================================
//控制 动因详情模态框 显示与隐藏
const driverDetailVisiable = inject('driverDetailVisiable')

//当前 激活 动因分组
const currentActiveTabKey = inject('currentActiveTabKey')

//控制  动因项详情模态框 显示与隐藏
const driverItemDetailVisiable = ref(false)
provide('driverItemDetailVisiable',driverItemDetailVisiable)

//与 父组件 通信
const emits = defineEmits(['selfConfirmReturnParam','autoGenDriverCode']);

//获取父组件参数
const props = defineProps({
    driverParam: Object,
    preSaveDriverArr:Array
});


//==================================================================【从子组件获取维度项信息(DriverItemDetail)】
function getDriverItemInfo(driverItemDetails){
// 分析： driverItemDetails 包含dimName dimTitle dimItemCode dimItemName，其中维度信息一致，需根据dimName 在dimAndItemInfoArr中做更新
    if (driverItemDetails.length > 0){
        let currentDimName = driverItemDetails[0].dimName
        let currentDimTitle = driverItemDetails[0].dimTitle

        //添加操作 和 编辑操作  都需要  更新维度项数据
        //查询旧数据边界（左边界，右边界）
        let left = 0
        let right = -1
        for (let i = 0; i < dimAndItemInfoArr.length; i++) {
            const curInfoItem = dimAndItemInfoArr[i]
            if (curInfoItem.dimName !== currentDimName) {
                if (right === -1) {
                    left++
                }else {
                    break;
                }
            }else {
                right = i
            }
        }
        //子组件传递的维度项 属于 一个新增维度
        if (right === -1) {
            dimAndItemInfoArr.push(...driverItemDetails)

            //子组件传递的维度项 已经存在需要替换
        }else {
            dimAndItemInfoArr.splice(left,right - left + 1,...driverItemDetails);
        }

//添加操作  和  编辑操作，需要同步 dimInfoArr。
        if (processDimType.value === 0) {
            let tempObject = reactive({
                dimName:currentDimName,dimTitle:currentDimTitle,dimItemCount:driverItemDetails.length
            })
            dimInfoArr.push(tempObject)
        }

        if (processDimType.value === 1) {
            let findIndex = dimInfoArr.findIndex(item=>{
                return item.dimName === currentDimName
            })
            if (findIndex !== -1) {
                dimInfoArr[findIndex].dimItemCount = driverItemDetails.length;
            }else {
                //编辑 转 添加操作
                processDimType.value = 0
                deleteDim(selectedDimItemArr[0].dimName)
                getDriverItemInfo(driverItemDetails)
            }

            //编辑 处理过的selectedDimItemArr需要置空
            selectedDimItemArr.splice(0,selectedDimItemArr.length)
        }

    }
}

//================================================【组件属性】============================================================
//动因详情模态框标题
const modalTitle =computed(()=>{
    return props.driverParam.processType === 0?'添加动因':'编辑动因'
})

//监听 父组件 传来的 处理类型
watch(()=>props.driverParam,async (newValue)=>{
    if (newValue.processType === 0){
        driver.name = ''
        dimInfoArr.splice(0,dimInfoArr.length)
        dimAndItemInfoArr.splice(0,dimAndItemInfoArr.length)
    }
    if (newValue.processType === 1){
        initDriverInfo()
    }
},{deep:true,immediate:true})

watch(driverDetailVisiable,async (newValue)=>{
    if (newValue && props.driverParam.processType === 0 && isEnterFromDriverTable.value) {
       emits('autoGenDriverCode',callback =>{
           driver.code = callback
           isEnterFromDriverTable.value = false
       })
    }
})

// 动因编码 自动转为大写
watch(()=>driver.code,(newValue)=>{
    if (newValue !== '') {
        driver.code = driver.code.toUpperCase()
    }
},{deep:true})
//================================================【普通方法】============================================================
//==================================================================【初始化 动因 信息】
function initDriverInfo() {
        driver.code = props.driverParam.processData.code
        driver.name = props.driverParam.processData.name

        //还原维度信息数组
        dimInfoArr.splice(0,dimInfoArr.length)
        //还原维度项信息数组
        dimAndItemInfoArr.splice(0,dimAndItemInfoArr.length)

        let dimItemList = props.driverParam.processData.driverItemList;
        for (let i = 0; i < dimItemList.length; i++) {
            const dimInfoItem = reactive({dimName:dimItemList[i].dimName,dimTitle:dimItemList[i].dimTitle})

            //一个维度  只  保存一次
            const findIndex = dimInfoArr.findIndex(item=>{
                return item.dimName === dimInfoItem.dimName
            })
            if (findIndex === -1) {
                dimInfoArr.push(dimInfoItem)
            }

            const dimAndItemInfo = reactive({
                dimName:dimItemList[i].dimName,
                dimTitle:dimItemList[i].dimTitle,
                dimItemCode:dimItemList[i].memberCode,
                dimItemName:dimItemList[i].dimItemName,
                formula:dimItemList[i].driverItemFormula.formula,
            })
            dimAndItemInfoArr.push(dimAndItemInfo)
        }

        //给 每个 维度 设置 其 维度项 个数
        for (const dimElement of dimInfoArr) {
            let dimItemCount = 0
            for (let i = 0; i < dimAndItemInfoArr.length; i++) {
                let dimAndItemInfoArrElement = dimAndItemInfoArr[i];
                if (dimAndItemInfoArrElement.dimName === dimElement.dimName) {
                    dimItemCount = dimItemCount +1
                }
                dimElement.dimItemCount = dimItemCount
            }
        }
}


//==================================================================【添加维度】
function addDim() {
    processDimType.value = 0
    driverDetailVisiable.value = false
    driverItemDetailVisiable.value = true
}


//==================================================================【编辑维度】
const selectedDimItemArr = reactive([])
// 动因 中 维度信息 处理类型 0 新增 1编辑
const processDimType = ref(-1)
function modifyDim(dimName,dimTitle) {
    //获取 当前动因 指定维度 下 的动因项（可以看做在选取维度项）
    const tempArr = dimAndItemInfoArr.filter(item=>{
        return item.dimName === dimName
    })

    selectedDimItemArr.length = 0
    for (let i = 0; i < tempArr.length; i++) {
        let tempObject = reactive({
            dimItemCode:tempArr[i].dimItemCode,
            dimItemName:tempArr[i].dimItemName,
            dimName:dimName,
            dimTitle:dimTitle
        })
        selectedDimItemArr.push(tempObject);
    }

    processDimType.value = 1
    driverDetailVisiable.value = false
    driverItemDetailVisiable.value = true
}


//==================================================================【删除维度】
function deleteDim(dimName) {
    //需要删除两部分
    //dimInfoArr  中dimName 等于 当前选中的
    for (let i = 0; i < dimInfoArr.length; i++) {
        if (dimInfoArr[i].dimName === dimName) {
            dimInfoArr[i].preDelete = true
        }
    }

    const tempArr1 = dimInfoArr.filter(filterItem=>{
        return !filterItem.preDelete
    })

    dimInfoArr.splice(0,dimInfoArr.length,...tempArr1);

    //dimAndItemInfoArr  中dimName  等于  当前选中的
    for (let i = 0; i < dimAndItemInfoArr.length; i++) {
        if (dimAndItemInfoArr[i].dimName === dimName) {
            dimAndItemInfoArr[i].preDelete = true
        }
    }

    const tempArr2 = dimAndItemInfoArr.filter(filterItem=>{
        return !filterItem.preDelete
    })

    dimAndItemInfoArr.splice(0,dimAndItemInfoArr.length,...tempArr2)

}

//==================================================================【表单验证相关】
const driverDetailFormRules = {
    code: [
        {
            required: true,
            message: '请输入动因编码',
        },{
            asyncValidator: (rule, value) => {
                return new Promise((resolve, reject) => {
                    if (value.length > 50) {
                      reject('动因编码长度不能超过50个字符')
                    } else if (/[/\\*<>"'\\|?:]/.test(value)) {
                      reject('动因编码不能包含\\ 、/ 、: 、* 、? 、" 、\' 、< 、> 、|中任意字符')
                    } else if (!/^[a-zA-Z]\w{0,49}$/.test(value)) {
                      reject('动因编码只能由字母、数字和_组成,并且以字母开头')
                    } else if (props.driverParam.processType === 0) {
                        let tempObject = reactive({
                            code: value
                        })
                        let tempArr = reactive([])
                        tempArr.splice(0, tempArr.length, tempObject)
                        context.getPlugin('http').post(`abc/model/driver/driverCodeCheckViaExistedDrivers/${currAbcModelGuid.value}`, tempArr).then(res => {
                            if (!res.data.checkValue) {
                                reject('当前动因编码在数据库中已经存在，请编辑')
                            } else {
                              /*  情况：上一次添加某个动因A（编码driverA）,子组件返回的数据只添加到父组件DriverTable的showAndEditList中，并没有与后端交互进行持久化
                                       之后再次点击 添加，此时需要判断新添加的动因编码 是否（与driverA）冲突。  当此类情况重复发生时，需要基于showAndEditList进行校验*/
                                const findIndex = props.preSaveDriverArr.findIndex(findItem=>{
                                    return findItem.code === value
                                })

                                if (findIndex !== -1){
                                    reject('当前动因编码在待保存内容中已经存在，请编辑')
                                }else {
                                    resolve()
                                }
                            }
                        })
                    }else {
                        resolve()
                    }
                })
            }
        }
    ],
    name: [
        {
            required: true,
            message: '请输入动因名称',
        },{
            asyncValidator: (rule, value) => {
                return new Promise((resolve, reject) => {
                    if (value.length > 50) {
                        reject('动因名称长度不能超过50个字符')
                    } else if (/\.$/.test(value)) {
                        reject('动因名称不能以.结尾')
                    } else if (/[/\\*<>"'\\|?:]/.test(value)) {
                        reject('动因名称不能包含\\ 、/ 、: 、* 、? 、" 、\' 、< 、> 、|中任意字符')
                    } else {
                        resolve()
                    }
                })
            }
        }
    ],
    dimInfoArr: [
        {
            asyncValidator: () => {
                return new Promise((resolve, reject) => {
                    if (dimInfoArr.length === 0) {
                        reject('请添加维度信息')
                    } else {
                        resolve()
                    }
                })
            }
        }
    ]
}

const driverDetailForm = ref(null)
//==================================================================【动因详情模态框---确认操作】
const loading = ref(false)

function confirmAction() {
    if (loading.value) {
        return
    }
    loading.value = true
    driverDetailForm.value.validate().then(validateResult => {
        if (!validateResult) {
            if (props.driverParam.processType === 0) {
                const driverInfo = reactive({
                    id: '',
                    code: driver.code,
                    name: driver.name,
                    belongDriverGroupId: currentActiveTabKey.value,
                    belongModelId: currAbcModelGuid.value,
                    dimNameList: [],
                    driverItemList: []
                })
                for (let dimInfoArrElement of dimInfoArr) {
                    driverInfo.dimNameList.push(dimInfoArrElement.dimName)
                }

                for (let i = 0; i < dimAndItemInfoArr.length; i++) {
                    const dimItem = dimAndItemInfoArr[i]
                    const driverItemInfo = reactive({
                        code: '',
                        name: '',
                        dimName: '',
                        dimTitle: '',
                        memberCode: '',
                        dimItemName: '',
                        belongModelId: currAbcModelGuid.value,
                        belongDriverGroupId: currentActiveTabKey.value,
                        driverItemFormula: {
                            belongModelId: currAbcModelGuid.value,
                            formula: ''
                        }
                    })
                    driverItemInfo.dimName = dimItem.dimName
                    driverItemInfo.dimTitle = dimItem.dimTitle
                    driverItemInfo.memberCode = dimItem.dimItemCode
                    driverItemInfo.dimItemName = dimItem.dimItemName


                    let numberOfDigit = Number(i + 1).toString().length
                    let driverItemIndexPlus = -1
                    switch (numberOfDigit) {
                        case 1:
                            driverItemIndexPlus = '00' + Number(i + 1)
                            break
                        case 2:
                            driverItemIndexPlus = '0' + Number(i + 1)
                            break
                        case 3:
                            driverItemIndexPlus = Number(i + 1)
                            break
                    }

                    let driverItemCode = driver.code + driverItemIndexPlus

                    driverItemInfo.code = driverItemCode
                    driverItemInfo.name = dimItem.dimItemName

                    driverInfo.driverItemList.push(driverItemInfo)
                }

                emits('selfConfirmReturnParam', driverInfo)
            }

            if (props.driverParam.processType === 1) {
                //获取原有动因数据
                const targetIndex = props.preSaveDriverArr.findIndex(findItem => {
                    return findItem.code === driver.code
                })

                const targetDriver = props.preSaveDriverArr[targetIndex]

                targetDriver.name = driver.name

                targetDriver.dimNameList.splice(0, targetDriver.dimNameList.length)
                for (let dimInfoArrElement of dimInfoArr) {
                    targetDriver.dimNameList.push(dimInfoArrElement.dimName)
                }

                const processedDriverItemArr = []
                for (let i = 0; i < dimAndItemInfoArr.length; i++) {
                    // 当 dimItem 的 processed 为undefined 时，即为新添加元素
                    const dimItem = dimAndItemInfoArr[i]
                    const driverItemInfo = reactive({
                        code: '',
                        name: '',
                        dimName: '',
                        dimTitle: '',
                        memberCode: '',
                        dimItemName: '',
                        belongModelId: currAbcModelGuid.value,
                        belongDriverGroupId: currentActiveTabKey.value,
                        driverItemFormula: {
                            belongModelId: currAbcModelGuid.value,
                            formula: ''
                        }
                    })
                    driverItemInfo.dimName = dimItem.dimName
                    driverItemInfo.dimTitle = dimItem.dimTitle
                    driverItemInfo.memberCode = dimItem.dimItemCode
                    driverItemInfo.dimItemName = dimItem.dimItemName

                    //配置动因项取数公式
                    const findIndex = targetDriver.driverItemList.findIndex(preFindItem=>{
                        return preFindItem.dimName === dimItem.dimName && preFindItem.memberCode === dimItem.dimItemCode
                    })

                    if (findIndex !== -1) {
                        driverItemInfo.driverItemFormula.formula = targetDriver.driverItemList[findIndex].driverItemFormula.formula
                    }


                    let numberOfDigit = Number(i + 1).toString().length;
                    let driverItemIndexPlus = -1
                    switch (numberOfDigit) {
                        case 1:
                            driverItemIndexPlus = '00' + Number(i + 1)
                            break
                        case 2:
                            driverItemIndexPlus = '0' + Number(i + 1)
                            break
                        case 3:
                            driverItemIndexPlus = Number(i + 1)
                            break
                    }

                    let driverItemCode = driver.code + driverItemIndexPlus

                    driverItemInfo.code = driverItemCode
                    driverItemInfo.name = dimItem.dimItemName

                    processedDriverItemArr.push(driverItemInfo)
                }

                targetDriver.driverItemList.splice(0,targetDriver.driverItemList.length,...processedDriverItemArr)


                emits('selfConfirmReturnParam', targetDriver)

            }

            //下次从 driverTable 页面 进入时，确保一致
            isEnterFromDriverTable.value = true
            //加载状态结束
            loading.value = false
            //关闭 动因详情  模态框
            driverDetailVisiable.value = false
        } else {
            //下次从 driverTable 页面 进入时，确保一致
            isEnterFromDriverTable.value = true
            //加载状态结束
            loading.value = false
        }
    })
}

//==================================================================【动因详情模态框---取消操作】
function cancelAction() {
    //还原数据
    driver.code = ''
    driver.name = ''
    dimInfoArr.splice(0,dimInfoArr.length)


    //清空校验信息
    driverDetailForm.value.clearValidateResult()

    //下次从 driverTable 页面 进入时，确保一致
    isEnterFromDriverTable.value = true

    //关闭当前模态框
    driverDetailVisiable.value = false

}

</script>

<template>
    <j-modal
        v-model="driverDetailVisiable"
        :title="modalTitle"
        :fullscreenable='false'
        :mask="false"
        :mask-closable="false"
        :closable='!loading'
    >
        <j-modal-content size="small">
            <j-form
                ref="driverDetailForm"
                :rules="driverDetailFormRules"
                :model="driver"
                label-position="right"
                :label-width="66"
                class="driverDetailFormClass"
            >
                <j-form-item prop="code" label="动因编码" required>
                    <j-input v-model="driver.code" :disabled="props.driverParam.processType === 1" class="topInput"></j-input>
                </j-form-item>
                <j-form-item prop="name" label="动因名称" required>
                    <j-input v-model="driver.name" placeholder="请输入动因名称" class="topInput"></j-input>
                </j-form-item>
                <j-form-item prop="dimInfoArr" label="关联维度" required>
                    <div class="processDim">
                        <div
                            v-for="(item) in dimInfoArr"
                            :key="item.dimName"
                            class="dimArea"
                        >
                            <div class="selectedTextDescription">
                                {{item.dimTitle+'('+item.dimItemCount+'个维度项)'}}
                            </div>
                            <div class="buttonArea">
                                <j-button @click.prevent="modifyDim(item.dimName,item.dimTitle)">编辑</j-button>
                                <j-button @click.prevent="deleteDim(item.dimName)">删除</j-button>
                            </div>
                        </div>
                        <div>
                            <j-button @click.prevent="addDim">添加</j-button>
                        </div>
                    </div>
                </j-form-item>
            </j-form>
        </j-modal-content>
        <template #footer>
           <j-space style="justify-content: flex-end">
               <j-button @click="cancelAction" :disabled='loading'>取消</j-button>
               <j-button type="primary" :loading='loading' @click="confirmAction">确定</j-button>
           </j-space>
        </template>
    </j-modal>
    <DriverItemDetail
            :show="driverItemDetailVisiable"
            :selected-driver-item-arr="selectedDimItemArr"
            :process-type="processDimType"
            @selfConfirmReturnParam="getDriverItemInfo"
    >
    </DriverItemDetail>
</template>

<style scoped>
.topInput{
    width: 396px;
}
.processDim{
    /*border: 1px burlywood solid;*/
    width: 396px;
    display: flex;
    flex-direction: column;
}
.dimArea{
    /*border: 1px red solid;*/
    width: 396px;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}
.selectedTextDescription{
    width: 264px;
    height: 25px;
    padding-top: 5px;
    /*border: 1px red solid;*/
}
.buttonArea{
    width: 132px;
    height: 38px;
    /*border: 1px red solid;*/
    display: flex;
    flex-direction: row;
    gap: 6px;
}
.driverDetailFormClass > ._inline_wdnlo_8 > :nth-child(1){
    width: 7px;
}
</style>
